単語の合計を空白と各行の最後の4文字に分割する方法は?例えば、与えられた
1. placing
2. backtick
3. paragraphs
下に見たい
1. pla cing
2. back tick
3. pa ragr aphs
答え1
アッ解決策:
awk '{ c=0; for(i=length($2);i>0;i-=4) {a[++c]=(i-4>0)? substr($2,i-4+1,4) : substr($2,1,i)}
$2=""; for(i=length(a);i>0;i--) $2=$2 FS a[i] }1' file
出力:
1. pla cing
2. back tick
3. pa ragr aphs
答え2
Perl
これを使用して、lookarounds
次のことができます。
perl -pe 's/(?<=\w)(?=(?:\w{4})+$)/ /g'
つまり、特定の位置に立っているとき、左側には英数字があり、右側には文字列の最後まで少なくとも4つ以上の数字またはその倍数があります。そんな場所が存在する限り、そこに空間が置かれることになる。これを行うと、要求された変更はグローバルに影響を受けます。
私達はまたbash
これをすることができます:
#!/bin/bash
# symbolic constants
NL=$'\012'; # newline
SP=$'\040'; # space
# elementary regexes
alnum='[0-9a-zA-Z]'; # a single alphanumeric
alnums4=$(csh -c 'repeat 4 echo -n "$1"' "$alnum"); # 4 consecutive alnums
# main processing
while IFS= read -r line res; do
while c4=$(expr "$SP$line$NL" : ".*$alnum\($alnums4\)$NL")
do
res=${c4}${res:+"$SP"}${res-} line=${line%????}
done
printf '%s %s\n' "$line" "$res"
done
GNU sed
エディタを使用してください。
sed -Ee '
s/\S+/\n&\n/2; # enclose the 2nd field with markers
# a do-while loop to progessively move the right marker to the left,
# consuming 4 alnums in each iteration. Looping stops when 4 alnums+
# 1 alnum at the boundary remains.
:loop
s/(\n[[:alnum:]].*)([[:alnum:]]{4})\n/\1\n \2/
tloop
# clear out the markers when done
s/\n//g
'
答え3
を使用すると、sed
次のことができます。
sed '
G
:1
s/\([[:alpha:]]\)\([[:alpha:]]\{4\}\)\(\n\)/\1\3 \2/
t1
s/\n//
'
改行文字を実行マーカーとして使用します(改行文字は初期パターンスペースには表示されない文字です)。もともと最後に追加しました。その後、ABCDE<marker>
ABCDEが5つのアルファベット文字の場合、文字シーケンスではなく空白ではなくシーケンスで単語を処理したい場合は、置換できる文字を見つけるたびに[[:space:]]
それをアンループに置き換えます。最後にマーカーを削除しました。[^[:blank:]]
A<marker> BCDE
これにより、行末の単語のみが処理されます。
最後の単語だけでなく、すべての単語を分類するのははるかに簡単です。
sed -e :1 -e 's/\(.*[[:alpha:]]\)\([[:alpha:]]\{4\}\)/\1 \2/;t1'
printf 'abcd\u00e9e\u0301f\n'
入力に分解された文字(例:出力abcdééf
)が含まれている場合は、次のことができます。
perl -Mopen=locale -lpe 'while(s/.*(?=\w)\X\K(?:(?=\w)\X){4}/ $&/){}'
答え4
Perlを使用する(単一バイト文字のみを使用すると仮定):
perl -ne 'print scalar(reverse join " ", (reverse =~ /.{1,4}/g)), "\n"'
- 内部的には、
reverse
与えられた単語(実際には含まれている完全な入力行)が反転されます。 - 正規表現は、反対の単語を4つの文字の塊に分割します(元の単語の先頭から始まる最後の塊には少ない文字を含めることができます)。
join
このチャンクを文字列で連結しますが、その間にスペースがあります。reverse
連結文字列を外部に反転します。- スカラーコンテキストで
scalar
外部を強制的に実行するために使用されます。reverse
- 結果が出力されます
print
。
以下のコードは同じことを行いますが、キャンセルして使用し、scalar
次に割り当てます。"\n"
print
-p
-l
$_
perl -lpe '$_ = reverse join " ", reverse =~ /.{1,4}/g'