
次の入力があります。
XX3083136|bla-bla texthere texttt|[email protected]|SADFdsafsafd|ASDfasfdsafd|DSFSAFD|dsafasfd|sadfsad|
XX3083372|bla-bla-bla this is a text bla-bla|[email protected]|SDFsafas|SADFsa|DFSsdf|asdasdf|sadfdsafsaf|asdfsadf|
次の出力が必要です。
XX3083136|bla-bla texthere textt|[email protected] |SADFdsafsafd|ASDfasfdsafd|DSFSAFD|dsafasfd|sadfsad|
XX3083372|bla-bla-bla this is a te|[email protected] |SDFsafas|SADFsa|DFSsdf|asdasdf|sadfdsafsaf|asdfsadf|
したがって、違いは「|」間の最大テキスト長を制御する必要があるということです。指定された行の長さより短い場合は、「」を入力する必要があります。この例では、2行目は最大24文字に制限され、3行目は30文字以上でなければなりません。行ごとに異なる最大/最小制限が必要です。
Bashでどうすればいいですか?
答え1
少し追加:
printf
テキストの基本形式は次のとおりです。
%s # Print as is
%10 # Right justify minimum width print 10
%-10 # Left justify minimum width print 10
%.10 # Max width 10
%10.10 # Max width 10, min width print 10
%-10.10 # Left justify, max width 10, min width print 10
%*s # Same as above, but get number from arguments
%-*s # Same as above, but get number from arguments
...
非常に長いパターンを得るとき、どこや何かを追跡するのは少し混乱するかもしれません。簡単にする1つの方法は次のとおりです。
#!/bin/bash
usage()
{
printf "Usage: %s <FILE>\n" "$(basename "$0")" >&2
[[ -n "$1" ]] && echo "$1"
exit 1
}
if [[ ! -t 0 ]]; then
: # Piped to
elif [[ $# -eq 0 ]]; then
usage "Missing file."
elif [[ ! -r "$1" ]]; then
usage "Unable to read \`$1'."
else
# Accept input from file to file descriptor 0, aka stdin
exec 0< "$1"
fi
fmt=""
fmt="$fmt%s|" # F1
fmt="$fmt%-24.24s|" # F2
fmt="$fmt%-30s|" # F3
fmt="$fmt%-10.10s|" # F4
fmt="$fmt%-10.10s|" # F5
fmt="$fmt%-10s|" # F6
fmt="$fmt%-2.2s|" # F7
fmt="$fmt%-2.2s|\n" # F8
# Set IFS to newline and bar and read fields
# assigning them to f1 ... f8
#
while IFS=$'\n'"|" read f1 f2 f3 f4 f5 f6 f7 f8; do
printf "$fmt"\
"$f1" "$f2" "$f3" "$f4" \
"$f5" "$f6" "$f7" "$f8"
done <&0
または。たとえば、
while IFS=$'\n'"|" read f1 f2 f3 f4 f5 f6 f7 f8; do
printf "%s|%-*.*s|%-*s\n" \
"$f1" \
24 24 "$f2" \
30 "$f3"
done < "input"
単に線の解析であれば、awkは良い選択です。たとえば、
#!/usr/bin/awk -f
BEGIN {FS="|"}
/^/ {
printf "%s|%-24.24s|%-30s|%-10.10s|%-10.10s|%-10s\n",
$1, $2, $3, $4, $5, $6
}
または:
#!/usr/bin/awk -f
BEGIN {
FS="|"
}
/^/ {
printf "%s|%-*.*s|%-*s|%-*.*s|%-*.*s|%-*s\n",
$1,
24, 24, $2,
30, $3,
10, 10, $4,
10, 10, $5,
10, $6
}
答え2
printf
組み込み関数を使用して文字列を切り取ることができます。
$ printf '%.2s\n' 'azerty'
az
|
これを使用して、目的の場所に区切り文字を入力します。たとえば、次のようになります。
$ printf '%10s%10s%10s%10s%10s%10s\n' '|' '|' '|' '|' '|' '|'
| | | | | |
バラよりhttp://www.bash-hackers.org/wiki/doku.php/commands/buildin/printf