~1
ACCOUNT1
34765367
001
5637463648374
1
32476743
85468456875
003
~1
~2
ACCOUNT2
23587458745647
1
002343
2347938457
~2
.... SO ON
我想将其打印成以下格式的另一个文件:
ACCOUNT134765367001563746364837413247674385468456875003
ACCOUNT22358745874564710023432347938457
我在下面写了这样的东西,直到~9完美地工作,但是对于~10,它也将~10记录添加到~1记录,在~1记录的末尾。我想我需要更新我的正则表达式模式...请帮助
max_input=2
path1=/home
line_number_m=1
while [ ${line_number_m} -le ${max_input} ]
do
o_p=""
sed -n "/^${line_number_m},/^~{line_number_m}/p" ${path1}/temp_op.txt | sed
"s/^${line_number_m}//" > ${path1}/tmp.txt
while read val
do
if [ -z ${val} ]
then
continue
else
o_p=`echo ${o_p}``echo ${val}`
fi
done< ${path1}/tmp.txt
echo ${o_p} >>${path1}/tmp_output.txt
line_number_m=`expr ${line_number_m} + 1`
done
rm ${path1}/tmp.txt
tail -n +2 ${path1}/tmp_output.txt > ${path1}/output.txt
rm ${path1}/tmp_output.txt
exit 0
~1和~1内的记录可以是任何随机数或字符,甚至是如下所示的空格: 〜1 001 13324324343 共同 6 487364754557465 --2space 5874654657 --- 3空间 48567846574 4568746574657 --5spaces --- 〜1
我想要我的输出如下: 00113324324343COMMON6487364754557465--5874654657 --- 485678465744568746574657 -----
答案 0 :(得分:1)
试试这个,希望可以帮助你作为一个起点:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
if [[ $line == ACCOUNT* ]]
then
printf '\n%s' "$line"
elif [[ $line != ~* ]]
then
printf '%s' "$line"
fi
done < "$1"
将其保存到文件中并尝试:
./script.sh data.txt
同时查看以下答案:https://stackoverflow.com/a/2172367/1135424
# The == comparison operator behaves differently within a double-brackets
# test than within single brackets.
[[ $a == z* ]] # True if $a starts with an "z" (wildcard matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).
答案 1 :(得分:1)
在gawk或awk而不是sed对我来说更容易。 Awk已经处理了记录,所以它特别擅长这样的任务。您只需告诉它如何识别记录分隔符,以及您想要对字段执行的操作。在这种情况下,在偶数编号的记录中,我们删除所有空格,然后打印。
gawk -v RS='~[0-9]+' 'NR%2==0 {gsub(/[[:space:]]/,"");print}'
这依赖的gawk功能是复杂(正则表达式)RS
变量。在BSD或macOS中,您可能需要类似以下内容,在连接记录中的所有字段之前清空第一个字段:
awk -v RS='~' 'NR%2==0 {$1="";gsub(/[[:space:]]/,"");print}'
如果你真的想在sed中这样做,我想你可以用以下内容来捏造它:
sed -Ene $'H;${x;s/[[:space:]]//g;s/~[0-9]+A/\\\nA/g;s/~[0-9]*//g;p;}'
这会将整个文件放入保留空间,与awk脚本相同的空格减少,然后在清除字段分隔符的过程中重新添加换行符。
答案 2 :(得分:0)
管道:
$ sed '/^~/d' data | tr -d '\n' | sed -re 's/(.)A/\1\nA/g' -e 's/$/\n/'
ACCOUNT134765367001563746364837413247674385468456875003
ACCOUNT22358745874564710023432347938457
sed
删除所有以~
开头的行。tr
将所有内容连接成一行输出。sed
使用字符A
(ACCOUNT
)作为分隔符再次将输入分成单独的行,并在末尾添加换行符。最后sed
要求GNU sed
能够使用\n
插入换行符。
答案 3 :(得分:0)
$ sed '/^~/d' data | awk -v RS='A' -v OFS='' '$1 && $1=RS $1'
ACCOUNT134765367001563746364837413247674385468456875003
ACCOUNT22358745874564710023432347938457
这是我对这个问题的第二个解决方案。
首先sed
删除所有以~
开头的行。
awk
然后将剩余数据作为由字符A
分隔的记录读取,并在输出字段之前连接字段(没有分隔符)。
这不依赖于GNU实用程序。
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed -rn '/^~/{:a;N;/^(~[0-9]+)\n(.*)\n\1$/!ba;s//\2/g;s/\s//g;p}' file
收集连续分隔符之间的行,即以~n
开头的行,其中n是整数。取下分隔符,去除空白区域并打印。