2016-11-30 28 views
0

我对bash脚本的语法没有用处。我正在尝试阅读文件。对于每一行,我希望只保留分隔符“/”之前的字符串部分,并且如果该词尊重特定长度,则将其放回到新文件中。我已经下载了一本字典,但格式不符合我的期望。由于有84000个单词,因此我不想在每个单词的'/'之后手动删除它。我虽然这将是一件容易的事情,并且我在本网站的其他类似问题上遵循了一些想法,但似乎我在某处丢失了某些东西,因为它仍然不起作用。我无法得到正确的长度。文件Test_Input每行包含一个字。下面的代码:需要在bash脚本中对字符串进行操作的帮助

#!/usr/bin/bash 
filename="Test_Input.txt" 
while read -r line 
do 
    sub= echo $line | cut -d '/' -f1 
    length= echo ${#sub} 
    if $length >= 4 && $length <= 10; 
     then echo $sub >> Test_Output.txt 
    fi 
done < "$filename" 
+0

THX都是别人的最好的工具做出来:) – David

回答

0

几个项目:

  1. 我假设你一直使用单一反引号的任务,而不是从字面上sub= echo $line | cut -d '/' -f1,因为这将有一定失败。或者,你也可以用sub=$(),如$(echo $line | cut -d '/' -f1)
  2. if条款所需要的条件,通过单人或双人[]涵盖,这样的:if [[ $length -ge 4 ]] && [[ $length -le 10 ]];
  3. 这使我下一个问题:<=不可靠在bash工作。只需使用-ge表示“较大或相等”,-le表示“较小或相等”。
  4. 如果您的线路不包含任何/字符,则在您的版本sub中将包含整行。这可能不是您想要的,所以我建议还要将-s标志添加到cut
  5. 您不需要somevar=$(echo $someothervar)。只需使用somevar=$someothervar

这里是可用的版本:

#!/usr/bin/env bash 
filename="Test_Input.txt" 
while read -r line 
do 
    sub=$(echo $line | cut -s -d '/' -f 1) 
    length=${#sub} 
    if [[ $length -ge 4 ]] && [[ $length -le 10 ]]; 
     then echo $sub >> Test_Output.txt 
    fi 
done < "$filename" 

当然,你也可以只使用sed

sed -n -r '/^[^/]{4,10}\// s;/.*$;;p' Test_Input.txt > Test_Output.txt 

说明:

  • -n别除非明确表示要打印任何东西打印。
  • -r使用扩展的正则表达式
  • /<searchterm>/ <operation>搜索符合一定条件的,并执行该操作线:
    • 搜索关键词是:^[^/]{4,10}\/从行的开头,应该有非4和10之间 - 斜线后面加斜杠
    • 操作是:s;/.*$;;p用空白替换第一个斜杠和行尾之间的所有内容,然后打印。
+0

只是一点点精度,双'[['没工作所有,我使用单一的。非常感谢你!我知道我不是很远! :) – David

+0

终于'[['工作好!似乎用'sh。/ script.sh'而不是'bash。/ script.sh'来加载我们的脚本具有较低的兼容性。 – David

0

awk是这个

awk -F/ 'length($1) >= 4 && length($1) <= 10 {print $1} > newfile