words.txt
Linuxシステムには、次の行を含むファイルがあります。各文字列をどのように繰り返しuser
て、1から4までの数字を追加apple
できますか?banana
user
apple
banana
予想出力:
user1
user2
user3
user4
apple1
apple2
apple3
apple4
banana1
banana2
banana3
banana4
以下を試しましたが、1つの文字列でのみ機能します。
seq 1 4 | awk {'print $0 "user"'}
答え1
awk
標準ツールボックスはおそらく最良の選択肢でしょう。
awk -v min=1 -v max=4 -v increment=1 '
{for (i = min; i <= max; i += increment) print $0 i}' words.txt
GNUツールからインスピレーションを得る@JJoao 2つのファイルラインのデカルト積を取得する方法:
join -t $'\n' -j2 -o1.1,2.1 words.txt <(seq 4) | paste -d '\0' - -
2番目のフィールドにwords.txt
結合して出力する場合seq 4
、ここではフィールド区切り文字を改行で定義したため、2番目のフィールドはありません。つまり、2 つのファイルの各行に対して 2 番目のフィールドがすべて空であるため、最終的にすべてを結合します。
答え2
sed 's/.*/&1\n&2\n&3\n&4/' words.txt
各行()のすべての項目を置き換え、(s
コマンド)全体に複数回表示される()を一致させ、英数字と改行文字を追加します。.*
&
答え3
一般的なbashの使用:
while IFS= read -r word; do printf "${word}%d\\n" {1..4}; done < words.txt
ただし、変数をprintf形式の文字列に入れると、予期しない文字が発生する可能性があります。たとえば、
$ cat words.txt
with \n newline
with %s directive
$ while IFS= read -r word; do printf "${word}%d\\n" {1..4}; done < words.txt
with
newline1
with
newline2
with
newline3
with
newline4
with 1 directive2
with 3 directive4
バックスラッシュシーケンスが解釈され、%
指示が遵守されます。これを保護するために、単純な1行の解決策は次のとおりです。
while IFS= read -r word; do
tmp1=${word//%/%%}
tmp2=${tmp1//\\/\\\\}
printf "${tmp2}%d\\n" {1..4}
done < words.txt
どの出力
with \n newline1
with \n newline2
with \n newline3
with \n newline4
with %s directive1
with %s directive2
with %s directive3
with %s directive4
答え4
ファイルの長さが実際には4行にすぎない場合は、次のように簡単な操作を実行できます。
$ while read word; do seq 1 4 | awk -v w="$word" '{print w$0}'; done < words.txt
user1
user2
user3
user4
apple1
apple2
apple3
apple4
banana1
banana2
banana3
banana4
しかし、これは良い考えではありません。シェルを使用してこのようなことを行うので、ここにデフォルトのGNU awk(元の順序を維持するため)ソリューションがあります。
$ gawk '{ words[$0] }END{for (word in words){ for(i=1;i<5;i++){printf "%s%d\n",word,i}}}' words.txt
user1
user2
user3
user4
apple1
apple2
apple3
apple4
banana1
banana2
banana3
banana4
このawk
方法を使用するには、ファイル全体をメモリに読み込む必要があります。スティーブンの答えより良いソリューションなので、代わりに使用することをお勧めします。