2017-04-30 135 views
3

我想打印每一個文件的所有文件名在目錄中一個.txt文件。打印列表(而不是文本文件本身)從終端

讓我們假設我有一個目錄,3個文件:

file1.txt 
file2.txt 
file3.txt 

,我試圖用ls > output.txt

的事情是,當我打開output.txt我發現這個名單:

file1.txt 
file2.txt 
file3.txt 
output.txt 

有沒有一種方法,以避免打印在那裏我重定向輸出的文件的名稱?或者更好的是,有一個命令能夠打印除一個目錄以外的所有文件的文件名?

+1

是否有一個原因,你必須打印輸出在同一目錄中的其他文件? – Jeremy

+2

@Jeremy對我來說使用它更簡單。但是,是的,我可以在另一個目錄中創建文件,完全避免該問題。我沒有想到 – jackscorrow

回答

5
printf '%s\n' * > output.txt 

注意,這個假設沒有預先存在output.txt文件 - 如果是這樣,先刪除它。

  • printf '%s\n' *使用globbing (filename expansion)通過線保持強勁打印所有文件,並且在當前目錄下的子目錄,行的名稱。

  • 通配發生之前output.txt通過輸出重定向> output.txt(這仍然發生前的命令是執行,這說明你的問題)創建的,所以在輸出中包含它的名字是

  • Globbing還避免使用ls,其在腳本中的使用是generally discouraged

1

一般情況下,這是不好的解析的ls輸出,尤其是在編寫需要在良好的信譽很長一段時間的生產質量腳本。看到這個頁面,以找出原因:Don't parse ls output

在你的榜樣,output.txtls > output.txt輸出的一部分,因爲shell中運行ls之前安排的重定向(到output.txt)。

得到您的情況下,正確的行爲,最簡單的方法是:

ls file*txt > output.txt # as long as you are looking for files named that way 

,或者存儲在一個隱藏的文件輸出(或其他某個目錄中一個正常的文件),然後將其移到最後的地方:

ls > .output.txt && mv .output.txt output.txt 

一個更通用的解決方案將使用grep -v

ls | grep -vFx output.txt > output.txt 

或者,您可以使用數組:

files=("$(ls)") 
printf '%s\n' "${files[@]}" > output.txt 
+2

我認爲它仍然與多行文件名相沖突,其中一行是'output.txt'(無可否認是一個奇特的情況)。至於另一種解決方案:爲什麼不使用字符串變量而不是單元素數組? '文件= 「($ LS)」; printf'%s'「$ files」> output.txt' – melpomene

0

最安全的方式,而不承擔有關文件名什麼,是使用bash陣列(內存)或臨時文件。臨時文件不需要內存,所以它可能更安全。喜歡的東西:

#!/bin/bash 
tmp=$(tempfile) 
ls > $tmp 
mv $tmp output.txt 
0

ls有一個忽略選項,我們也可以使用find命令。

  • 使用ls與忽略選項

    ls -I "output.txt" > output.txt 
    ls --ignore "output.txt" > output.txt 
    

-I, --ignore相同。這個選項和man page一樣,不要列出匹配shell PATTERN的隱含條目。

  • 使用findfind

    find \! -name "output.txt" > output.txt 
    

-name選項查找文件/目錄,其名稱相匹配的模式。 ! -name不包括名稱與模式相匹配的名稱。

find \! -name "output.txt" -printf '%P\n' > output.txt 

%P條路徑,並給出唯一的名字。

+1

您的命令假定使用_GNU_工具(Linux) - 請在您的答案中清楚說明這一先決條件。對於'find'命令是等價的,你(a)需要'-maxdepth 1'來防止遞歸,並且(b)你必須對文件名列表進行排序。 – mklement0

+0

我的機器上沒有忽略選項。我沒有使用Linux – jackscorrow