xargsとライン別パイプ

xargsとライン別パイプ

a.txtb.txtおよび3つのファイルがあります。 、単純なテキストを含む3c.txtつのファイルを作成したいと思います。a.testb.testc.testabracadabra

基本的には、ポイントは.test各ファイルのファイルを作成し、.txtテキストで埋めることです。xargsそれでこれをやろうとしています。

anlx2626> ls
a.txt  b.txt  c.txt

anlx2626> ls *.txt | awk -F'.txt' '{print $1}' | xargs -I {} echo "abracadabra" > {}.test

anlx2626> ls *.test
ls: No match.

{}ライン別配管にプレースホルダを使用することが期待どおりに機能しない理由を指摘できる人はいますか?

答え1

このコードでは:

xargs -I {} echo "abracadabra" > {}.test

xargsはリダイレクト演算子をまったく表示できません>。これはシェルによって解釈され、.xargsというファイルを生成します {}.test

xargsを使用して要求された操作を実行する1つの方法は、shにリダイレクト演算子を解釈させることです。

xargs sh -c 'for i do echo abracadrabra > "$i"; done' sh

しかし、xargsをまったく使用しない方が良いでしょう。他の答えは方法を説明します。

答え2

awkテキストを出力できます。いいえechoまたは必須ですxargs。あなたのアプローチにはfoo-1.2.txt

改行文字を含むか、名前が.txt

今回はここでループを使用します(例:zshを使用)。

(set -o noclobber; for f (*.txt(N)) echo abracadabra > $f:r.test)

またはPOSIXとして:

(set -o noclobber
 for f in *.txt; do
   echo abracadabra > "${f%.*}.test"
 done)

これはnoclobber、既存のファイルが上書きされるのを防ぐためです。隠しファイルは無視されます。txtPOSIX shバリアントは、ファイルが存在しない場合はファイルを生成します*.test

答え3

この質問に対する回答はすでにすべて完了していますが、他の方法を示すために次のように追加しました。

while IFS= read -r
do
echo abracadabra > "${REPLY}.test"
done < <(find . -maxdepth 1 -name "*.txt" -exec basename -s .txt {} \;)

ここで、 find はテキストファイルをリストするために使用されます。maxdepthfindがサブフォルダに繰り返されるのを防ぐために使用されます。basename -s .txtリスト名を除いてはまったく必要ないので、txt拡張子を最初から削除するために使用されます。 whileループでは、拡張子なしで名前を使用し、文字列置換を使用してファイル.testにエコー中に拡張子を追加します。私たちはデフォルト変数を使用しましたwhile$REPLY

答え4

for l in $(ls *.txt); do echo "abrakadabra" > $l; done

関連情報