繁体   English   中英

如何从文件中的每一行的字符串中选择第n个字符?

[英]How to select the nth char from a string for each line in a file?

每一行都有一个单词和一个数字。 我需要以某种方式选择第n个字母,它们将共同构成一个新词。 例如:

and 3
for 3
map 2
wrestle 1

draw

它必须像这样开始

cat char.txt | ...

我只允许使用sed(没有awk,perl,...)。

我知道如何选择所有数字

sed 's/\(.*\) \(.*\)/\2/g'

或文字

sed 's/\(.*\) \(.*\)/\1/g'

而我在考虑

cat char.txt | head -c $(sed 's/\(.*\) \(.*\)/\2/g') | tail -c 1 | sed 's/\n\//g'

但它不会起作用,因为它不会迭代思考所有的行,并且由于某种原因它甚至不会在一行上工作。

需要一些帮助和指导

while read w n; do echo -n ${w:(($n-1)):1}; done < filename

输出:

draw

${parameter:offset:length}: 
   Substring Expansion. Expands to up to length characters of parameter
   starting at the character specified by offset.

这是一个解决这个难题的sed脚本,假设找到的数字在1-9范围内:

s/ /@@@@@@@@@@ /
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 1$/\1/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 2$/\2/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 3$/\3/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 4$/\4/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 5$/\5/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 6$/\6/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 7$/\7/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 8$/\8/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 9$/\9/
H
$!D
${x;s/\n//g;}

第一行用@ s填充当前行上的字,以确保字段中至少有10个字符。 9个后续行用给定位置的字符替换模式空间。 H将该字符存储在保留空间中,前面带有换行符。 除非读取了最后一行,否则我们将丢弃模式空间并重新开始。 如果已经读取了最后一行,我们将模式空间与保留空间交换,保留空间保存所需的单词垃圾邮件,我们删除了换行符。

将其保存在文件script.sed我们获取

% sed -f script.sed < data
draw

实施支持1-19范围内的字符偏移的版本的迷人练习留给读者练习。

我们可以用awk更轻松地解决这个难题:

% awk '{answer=answer substr($1,$2,1)}END{print(answer)}' < data
draw

仅使用sed(抱歉避免使用cat char.txt: - ;

sed -n ':a
/1$/ !{
   s/.//
   h
   s/.* \([0-9]\)$/\1/
   y/98765432/87654321/
   G
   s/\(.\)\n\(.*\) [0-9]/\2 \1/
   b a
   }
s/\(.\).*/\1/p' char.txt

假设您只采用第1列到第9列(单个数字),但可以通过适应“巨大数字”进行扩展。 它也可以通过'简单'在每行写一个字符1 char(所以verticaly)。 也可以修改bu重载代码。

原则:如果最后一位不是1,则删除第一个字符并减少1.如果它等于1,则打印该行的第一个字符。

  • 测试最后一位数是/1$/
  • 减少是由翻译y/98765432/87654321/
  • s/.//删除第一个字符
  • 另一种是通过复制线使用工作和保持缓冲区(仅修改最后一位数部分)的演示文稿,只留下数字,减少,添加原始行并重新排列新数字代替最后一个旧数字
  • 到达digit = 1,in不进入流程并仅保留第一个字符,然后按s/\\(.\\).*/\\1/p打印s/\\(.\\).*/\\1/p

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM