aとbのみを含むファイルがあります。
aaaaaaaaaaaaaabbbbbb
abababaaaabbbaabababa
bbbbbaaaaaa
aaabbbabbbaaaabbaba
abababbabbababbbabbab
abababbababaabaaabbababbaba
bababbbababba
私は次のようにsedを使用してbの前にすべてのaをソートしたいと思います。
aaaaaaaaaaaaaabbbbbb
aaaaaaaaaaaabbbbbbbbb
aaaaaabbbbb
aaaaaaaaaabbbbbbbbb
aaaaaaaabbbbbbbbbbbbb
...
このスクリプトを作成しようとしています。
for row in $(sed -n 'p' $1)
do
for k in $(seq $((${#row}-2)))
do
for j in $(seq $((${#row}-k-1)))
do
if [[ "${row:$j:1}" == a && "${row:$j+1:1}" == b ]]; then
sed -e "s/./a/$j+1/p" $row >> out.txt
fi
done
done
done
しかし、それはうまくいかず、実際にそれを動作させる方法を知りません。しかし、このスクリプトを書いた後、sedタグを使用する方が簡単かもしれません。
しかし、「a」が「b」の前にあることを確認するために、sedでテスト条件を設定する方法、またはsedでループ数を設定する方法は何ですか?
答え1
test.txtというファイルを作成し、次のコマンドを実行しました。
sed -e ':loop' -e 's/ba/ab/' -e 't loop' test.txt
答え2
やや効率的なアプローチsed
:
sed 'h; s/b//g; x; s/a//g; H; x; s/\n//' file.txt
そしてperl
:
perl -lpe '$_ = y/b//dr . y/a//dr' file.txt
別の方法perl
:
perl -lpe '$_ = join "", sort split //' file.txt
(これは"a" lt "b"
)のために動作します。
GNUの使用awk
:
awk '{ print gensub(/b/, "", "g") gensub(/a/, "", "g") }' file.txt
そしてbash
:
while read -r line; do
printf '%s%s\n' "$( tr -d b <<<"$line" )" "$( tr -d a <<<"$line" )"
done <file.txt
答え3
if [[ "${row:$j:1}" == a ...
これを行うには、シェルですべてのことができると思います。
while read -r s ; do
for (( i = 0 ; i < ${#s} ; i++ )) ; do
[ "${s:i:1}" = "a" ] && astr+=a || bstr+=b
done
echo "$astr$bstr"
done
答え4
perl -pe 's/(b+)(a+)/$2$1/ while /ba/' data.file
レコードに「b」と「a」が含まれている限り、現在のレコードからBeeとAceの「島」を反転し続けます。
perl -F\(b+\) -lne '
my @A;
splice @A, (/b/ ? @A : 0), 0, $_ for @F;
print @A;
' data.file
読み取ったレコード/行ごとに @A 配列を初期化します。レコードから切り取られたフィールド(@ Fに格納されている)を確認し、「b」が含まれている場合は配列の末尾にプッシュし、そうでない場合は先頭に配置します。最後に配列を印刷します。