次のファイルがあります
/folder/abc1.txt.gz
/folder/abc2.txt.gz
/folder/abc3.txt.gz
次の内容でtxtファイルを作成したいと思います。
abc1 /folder/abc1.txt.gz
abc2 /folder/abc2.txt.gz
abc3 /folder/abc3.txt.gz
次のコマンドを使用しました。
find /folder -name 'abc*.txt.gz' -type f -printf '%f %p\n' > out.txt
すると、以下が出力されます。
abc1.txt.gz /folder/abc1.txt.gz
abc2.txt.gz /folder/abc2.txt.gz
abc3.txt.gz /folder/abc3.txt.gz
ファイル名の最初の部分(.txt.gzを除く)とパスのみを持つことができる方法は何ですか?
答え1
常に同じ拡張子の場合は、次の方法で削除できます。
find /folder -name 'abc*.txt.gz' -type f -printf '%f %p\n' |sed 's/\.txt.gz//'
このsed
コマンドは最初の項目のみを削除します.txt.gz
。
拡張機能を削除するには:
find /folder -name 'abc*.txt.gz' -type f -printf '%f %p\n' |sed 's/\.[^[:space:]]* / /'
拡張自体にスペースがないと仮定すると、最初のドットの後から最初のスペース.
まで、スペース以外のすべての文字が削除されます。
答え2
を使用して解決策を探し、サフィックスがファイルセット全体で一定であると仮定でき、次を使用しているbasename
ので、次を使用します。.txt.gz
bash
declare -a files
readarray -t files < <( find /folder -name '*.txt.gz' -type f )
for f in "${files[@]}"
do
printf '%s %s\n' "$(basename "$f" '.txt.gz')" "$f"
done
$ test.sh
abc1 /folder/abc1.txt.gz
abc2 /folder/abc2.txt.gz
abc3 /folder/abc3.txt.gz
答え3
シェルバッシュの場合:
find folder/ -name 'abc*.txt.gz' -exec bash -c ': ${0##*/}; echo ${_%%.*} $0' {} \;
:
空のコマンドですが、その引数は${0##*/}
内部$_
変数(前の単純コマンドの最後のパラメータ)。
答え4
basename
を使用してファイルからディレクトリパスとサフィックスを削除し、を使用してフルパス名を-print
印刷し、2つを結合しますpaste
。
find /folder -name 'abc*.txt.gz' -type f -exec basename {} .txt.gz \; -print |
paste - -
これにより、タブで区切られた2つの列を持つ出力行が作成されます。ここで、最初の列は見つかったファイルの出力、basename
2番目の列は見つかったファイルのフルパス名です。区切り文字で空白が必要な場合はをpaste -d ' ' - -
使用してくださいpaste - -
。
これは、挿入された改行文字を含まない名前に依存し、使用される区切り文字を含む名前は解析するのがpaste
難しいリストになる可能性があります。