如何正確使用tail連接所有隱藏文件
問題
我希望能夠:
- 連接目錄中的所有文件(正常和隱藏),
- 但我也想在每個連接的開頭顯示每個文件的標題。
我在網上找到了一些解決方案,我可以用
tail -n +1 * 2>/dev/null
超級巧妙的技巧來做#2,但它不包括隱藏文件,就像我要做的那樣:cat * .* 2>/dev/null
甚至head * .* 2>/dev/null
cat 命令可以解決問題,但不包含文件名,head 命令不會列印/連接每個文件的全部內容。
問題
有沒有辦法做我需要做的事情
tail
,如果不是什麼是實現相同結果/輸出的好替代品。更新一個例子
嘗試連接所有文件(正常和隱藏)時的 tail 命令
[kevin@PC-Fedora tmp]$ ls -la total 8 drwx------ 2 user user 4096 Jun 23 09:24 . drwxr-xr-x. 54 user user 4096 Jun 23 08:21 .. -rw-rw-r-- 1 user user 0 Jun 23 09:24 .f1 -rw-rw-r-- 1 user user 0 Jun 23 09:24 f1 -rw-rw-r-- 1 user user 0 Jun 23 09:24 .f2 -rw-rw-r-- 1 user user 0 Jun 23 09:24 f2 -rw-rw-r-- 1 user user 0 Jun 23 09:24 .f3 -rw-rw-r-- 1 user user 0 Jun 23 09:24 f3 -rw-rw-r-- 1 user user 0 Jun 23 09:24 .f4 -rw-rw-r-- 1 user user 0 Jun 23 09:24 f4 -rw-rw-r-- 1 user user 0 Jun 23 09:24 f5 [user@PC-Fedora tmp]$ tail -n +1 * ==> f1 <== ==> f2 <== ==> f3 <== ==> f4 <== ==> f5 <== [user@PC-Fedora tmp]$ tail -n +1 * .* ==> f1 <== ==> f2 <== ==> f3 <== ==> f4 <== ==> f5 <== ==> . <== tail: error reading '.': Is a directory [user@PC-Fedora tmp]$
使用
zsh
和 GNUtail
(並非所有尾部實現都可以採用多個文件名參數,並且並非所有實現都會顯示文件名):() { (($# == 0)) || tail -vn +1 -- "$@" < /dev/null; } *(ND)
-v
即使只有一個文件,D
對於dotglob,N
對於nullglob,仍然使用匿名函式列印文件名,該函式傳遞該glob的擴展並檢查目前目錄為空的特殊情況。
</dev/null``tail
是為了部分減輕 GNU在傳遞名為 的文件名-
時將讀取 stdin的事實。在這裡,我們只是阻止它讀取標準輸入,但它仍然不會讀取名為-
. 另一種方法是使用"${@/#%-/./-}"
代替"$@"
替換-
為./-
,但這也意味著您會看到文件而==> ./- <==
不是文件(仍然可能比 更好)。==> - <==``-``==> standard input <==
您可能還想添加
.
(or-.
) glob 限定符以限制正常文件,以避免錯誤或更糟,如果目前目錄 (*(ND-.)
) 中有目錄或其他類型的非正常文件。與
ksh93
GNU相同tail
:( FIGNORE='@(.|..)' set -- ~(N)* (($# == 0)) || tail -vn +1 -- "$@" < /dev/null )
與
bash
GNU相同tail
:( setopt -s nullglob dotglob set -- * (($# == 0)) || tail -vn +1 -- "$@" < /dev/null )
或者使用 GNU
tail
和任何 POSIXsh
(包括zsh
,但僅在sh
仿真中),也限制為正常文件或對正常文件的符號連結並替換-
為./-
,但可能以不同的順序處理文件,因為我們在.*
其他文件之前執行這些文件:( set -- for file in .* * [ -f "$file" ] || continue [ "$file" = - ] && file=./- set -- "$@" "$file" done [ "$#" -eq 0 ] || exec tail -n +1 -- "$@" )
或者您可以使用 GNU
awk
(此處為zsh
):() { (( $# == 0 )) || gawk 'BEGINFILE{ print sep "==> "substr(FILENAME, 3)" <==" sep = "\n" } {print}' "$@" } *(ND-.)
awk``tail
與-
包含=
. _ 我們通過添加./
我們在顯示時剝離的前綴來解決這兩個問題。請注意,如果文件末尾缺少,awk 會添加一個換行符。或使用循環:
sep= for f (*(ND-.)) { print -r "$sep==> $f <==" sep=$'\n' cat < $f }
(
cat
與 有同樣的問題-
,我們通過在標準輸入上傳遞文件而不是參數來解決這個問題)