UNIX: 異なる拡張子を持つファイルを 1 つのファイルに結合

UNIX: 異なる拡張子を持つファイルを 1 つのファイルに結合

たとえば、/temp ディレクトリに 100 個のファイルがあります。そのうち 50 個は .msg 拡張子で、50 個は .xml 拡張子です。

/temp/test1.xml
/temp/test2.xml
/temp/test3.xml
.........
/temp/test49.xml
/temp/test50.xml

そして

/temp/test1.msg
/temp/test2.msg
/temp/test3.msg
.........
/temp/test49.msg
/temp/test50.msg

テキスト ファイルで、.xml ファイルと .msg ファイルの内容を次々に組み合わせて出力したいと思います。たとえば、出力ファイルは次のようになります。

content of test1.xml
content of test1.msg
content of test2.xml
content of test2.msg
content of test3.xml
content of test3.msg
............
content of test49.xml
content of test49.msg
content of test50.xml
content of test50.msg

この /temp ディレクトリには、常に .msg ファイルと .xml ファイルが同数存在します。また、出力ファイルの内容の前にパスまたはファイル名を表示できますか? 例:

text1.xml: content of test1.xml 
text1.msg: content of test1.msg
text2.xml: content of test2.xml
text2.msg: content of test2.msg
text3.xml: content of test3.xml
text3.msg: content of test3.msg
....................
text49.xml: content of test49.xml
text49.msg: content of test49.msg
text50.xml: content of test50.xml
text50.msg: content of test50.msg

私は簡単なパイプをファイルしようとしました

cat * > text.txt

しかし、これでは必要な結果は得られません。出力ファイルでは、最初にすべての *.xml ファイルの内容がリストされ、次に *.msg ファイルの内容がリストされます。

手伝ってください。

答え1

for f in *xml ; do
  cat "$f" "${f/.xml/.msg}"
done > OUTPUTFILE

シェルを使用している場合は、これが機能する可能性がありますbash。それ以外の場合 (他の POSIX シェル) は、cat "$f" "${f%.xml}.msg"上記の行の代わりに: を使用しますcat

答え2

このような状況では、次のように進めるのが合理的であることが多いです。

  1. すべてのファイルをテキスト ファイルにリストします。

    $ ls > files
    
  2. テキスト ファイルを編集して、不要なファイルを削除し、残りのファイルを希望どおりの順序に並べます。

  3. 次に、次の操作を実行します (ファイル名にスペースや奇妙な文字が含まれていないことを前提とします)。

    $ cat $(cat files) > bigfile
    

このアプローチのバリエーションとして、テキストファイルを1つの大きなコマンドに変更する方法があります。

file1
file2
file with spaces 3
...
filen

に:

cat \
file1 \
file2 \
"file with spaces 3" \
... \
filen \
> bigfile

次に、ファイルをスクリプトとしてソースします。

$ . ./files

viを使用すると、バッファ内のすべての行にスペースとバックスラッシュを追加できます:%s/$/ \\/

答え3

for i in {1..50}; do
    echo "text$i.xml: `cat text$i.xml`" >> output.txt
    echo "text$i.msg: `cat text$i.msg`" >> output.txt
done

答え4

通常のシーケンスの場合は、次のようにします。

bashの場合:

for ITER in {1..50}
do
    cat test${ITER}.xml
    cat test${ITER}.msg
done > test.txt

またはユーティリティをお持ちの場合seq

for ITER in $(seq 1 50)
do
    cat test${ITER}.xml
    cat test${ITER}.msg
done > test.txt

関連情報