サンプルファイルがあります。
[root@localhost base_filters]# cat shortlist
2233|charles harris |g.m. |sales |12/12/52| 90000
9876|bill johnson |director |production|03/12/50|130000
5678|robert dylan |d.g.m. |marketing |04/19/43| 85000
2365|john woodcock |director |personnel |05/11/47|120000
5423|barry wood |chairman |admin |08/30/56|160000
,
姓の後にカンマがあるようにファイルの名前を反転したいと思います。たとえば、名前は harris,charles で読み取る必要があります。
私は次のコマンドを試しました: -
[root@localhost base_filters]# tr -s ' ' < shortlist | cut -d\| -f2 | cut -d' ' -f2,1
charles harris
bill johnson
robert dylan
john woodcock
barry wood
姓を最初に指定したいので、フィールド2を指定してから1を指定しましたが、うまくいかないようです。これについて考えていますか?
答え1
これはを使用して簡単に行うことができますawk
。まず、名前を印刷してから出力をもう一度awkにパイプします(今回はスペースをファイル区切り文字として使用します)。
awk -F "|" '{print $2}' extract.txt | awk -F " " '{print $2 "," $1}'
答え2
カットのマニュアルページには次のように記載されています。
選択した入力は、読み取った順序と同じ順序で書き込まれ、正確に一度書き込まれます。
だから切るのではなく、他のツールを使うべきです。たとえば、sed、awk、Perl、Python、bash です。
答え3
次の関数は、Bashの組み込み機能のみを使用して目的の操作を実行します(Bashを使用したい場合)。
foo ()
{
local filename="$1"
while IFS='|' read -r pre name suf; do
l="$pre|${name#* },${name% *}|$suf";
printf '%s\n' "$l";
done < "$filename"
}
これIFS変数一度に各行を読むには| 「読む」に設定してください。「1」(あなたのファイル)を3つの部分に分け、$前の$名前そして$suf、IFS値に基づいています。
$今後値は名前の前のフィールドに設定されます。$name変更する名前自体(2番目のフィールド)に設定し、$suf残りの行です。
私は使うパラメータ拡張(でParameter Expansionを検索することもできますman bash
)$name大地。
"${name#* }"
名前は削除され、姓は残ります。
"${name% *}"
姓が削除され、名前だけが残ります。
使用法:foo [/path/to/file.txt]
出力例:
nylon100@~$ cat>file.txt
123|first1 last1|foo|bar|date|baz
456|first2 last2|foo|bar|date|baz
789|first3 last3|foo|bar|date|baz
nylon100@~$ foo file.txt
123|last1,first1|foo|bar|date|baz
456|last2,first2|foo|bar|date|baz
789|last3,first3|foo|bar|date|baz
答え4
努力する:
tr -s ' ' < shortlist | cut -d\| -f2 | tr '\n' ' ' | tac -s' ' | \
sed -e 's/^[[:space:]]//' -e 's/ /\n/g' | sort
または、次のようなファイルが多い場合:
sortnames () {
tr -s ' ' < $1 | cut -d\| -f2 | tr '\n' ' ' | tac -s' ' | \
sed -e 's/^[[:space:]]//' -e 's/ /\n/g' | sort
}