Bashコマンドを使用して文字列と数値を1行から分離する方法。
例:私は含む文字列を持っています
string123anotherstr456thenanotherstr789
出力は次のようになります。
string
123
anotherstr
456
thenanotherstr
789
GNU grep
または互換性のあるソリューション:
s="string123anotherstr456thenanotherstr789"
grep -Eo '[[:alpha:]]+|[0-9]+' <<<"$s"
[[:alpha:]]+|[0-9]+
-正規表現の代替グループ。アルファベット文字または数字のいずれかに一致します。両方とも、出力では別個のエントリーと見なされます出力:
string
123
anotherstr
456
thenanotherstr
789
POSIXly:
string=string123anotherstr456thenanotherstr789
sed '
s/[^[:alnum:]]//g; # remove anything other than letters and numbers
s/[[:alpha:]]\{1,\}/&\
/g; # insert a newline after each sequence of letters
s/[0-9]\{1,\}/&\
/g; # same for digits
s/\n$//; # remove a trailing newline if any' << EOF
$string
EOF
[[:alpha:]]+
(文字のシーケンス)ごとと[[:digit:]]+
(数字のシーケンス)ごとに改行文字を追加します。
awk '{ gsub(/([[:alpha:]]+|[[:digit:]]+)/,"&\n",$0) ; printf $0 }' filename
(&
は、一致したシーケンスのawk
省略形です。)
以前と同じように、ただし[^[:alnum:]]+
(非文字、非数値)文字の部分文字列も処理するようになりました:
awk '{ gsub(/([[:alpha:]]+|[[:digit:]]+|[^[:alnum:]]+)/,"&\n",$0) ; printf $0 }' filename
-
(ハイフン)と.
(ピリオド)を数値として扱う:
awk '{ gsub(/([[:alpha:]]+|[[:digit:].-]+|[^[:alnum:].-]+)/,"&\n",$0) ; printf $0 }' filename
これらの文字は、[[:digit:].-]+
と[^[:alnum:].-]+
の両方の式に出現する必要があります。また、リテラルハイフンとして解釈するには、-
が各式の最後の右角かっこの前のlast文字である必要があります。それ以外の場合は、文字の範囲を示します。
例:
[test]$ cat file.txt
string123another!!str456.001thenanotherstr-789
[test]$ awk '{ gsub(/([[:alpha:]]+|[[:digit:].-]+|[^[:alnum:].-]+)/,"&\n",$0) ; printf $0 }' file.txt
string
123
another
!!
str
456.001
thenanotherstr
-789
入力ファイルで必要な場合は、awk
コマンドを次のように変更できます。
-
が数値シーケンスのstartで発生する場合にのみ、数値の一部としてカウントされることを確認します。GNU sed
(または互換性のある)ソリューション:
s="string123anotherstr456thenanotherstr789"
sed 's/[a-zA-Z]*\|[0-9]*/&\n/g; s/\n$//' <<<"$s"
出力:
string
123
anotherstr
456
thenanotherstr
789
python3
python3 -c '
from itertools import groupby
s = ("".join(g) for k, g in
groupby("string123anotherstr456thenanotherstr789", lambda x: x.isalpha()))
print(*s, sep="\n")
'
string
123
anotherstr
456
thenanotherstr
789
同じことを達成するために、1つのライナーの下で使用されます。テストされたように、それはうまくいきました
sed "s/[0-9]\{3\}/\n&/g" filename | sed "s/[0-9]\{3\}/&\n/g"| sed '/^$/d'
出力
string
123
anotherstr
456
thenanotherstr
789
私はまだPerlソリューションを見ていないので、ここに:
_$ cat s
string123anotherstr456thenanotherstr789
$ Perl -lne 'print $& while /[[:alpha:]]+|[[:digit:]]+/g' < s
string
123
anotherstr
...
_
もちろん、「数値」のより広い定義では、_[-+]?[0-9]+
_(先行符号)、[-+]?[0-9]+(.[0-9]+)?
(オプションの小数部)、または[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?
(プラスオプションの指数)。後者の2つには、小数点がある場合、小数点の前後に少なくとも1桁必要です。
これは、元の文字列のいくつかの(短い)コピーを作成するため、比較的非効率的です。
declare s=string123anotherstr456thenanotherstr789
while [[ "$s" =~ ^([a-z]+)([0-9]+) ]]; do
echo ${BASH_REMATCH[1]}
echo ${BASH_REMATCH[2]}
s="${s:${#BASH_REMATCH[0]}}"
done
1行あたり何組の文字と数字のペアを扱っていますか?
gawk '{ $1 = $1; print }' FPAT='[a-z]+|[0-9]+' OFS='\n' input.txt
テスト
gawk '{ $1 = $1; print }' FPAT='[a-z]+|[0-9]+' OFS='\n' <<< 'string123anotherstr456thenanotherstr789'
出力
string
123
anotherstr
456
thenanotherstr
789