sed を使用して b の前に a をバブリングします。

sed を使用して b の前に a をバブリングします。

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」が含まれている場合は配列の末尾にプッシュし、そうでない場合は先頭に配置します。最後に配列を印刷します。

関連情報