1

I have a set of 1-line .txt files in a directory. They all have the same basic format, which I have pasted below labelled 'input':

For every file in the directory, I would like to remove the string at the beginning and the end so that I only have the text that I am interested in, so that each file looks the 'output':

Input:
<s> Text here that I want to keep </s> (31ca4166c37a_.76)

Output:
Text here that I want to keep

Any help would be greatly appreciated.

2
  • Welcome! The strings beginning an end are always yhe same? Mar 24, 2020 at 16:33
  • The <s> and the </s> are always the same, and there is always a string in brackets at the end. The contents inside the brackets is different for each file. Thanks!
    – user401844
    Mar 24, 2020 at 17:09

5 Answers 5

1

Using good old ed to edit the files:

for file in dir/*.txt; do
  ed -s "$file" <<'EOF'
s!^<s> *!!
s!</s>.*$!!
w
EOF
done

(As a general rule, most of the time you find yourself thinking about the non-standard sed -i, you should consider using ed instead.)

0

With sed

sed -i.bak 's|^<\/s>\s\(.*\)\s<\/s>.*$|\1|' 1-line.txt

Tests

echo "</s> Text here that I want to keep </s> (31ca4166c37a_.76)" | sed 's|^<\/s>\s\(.*\)\s<\/s>.*$|\1|'
Text here that I want to keep

To apply in all files in a folder there is no way to do it using only sed. You'll need to use at least the find utility together:

find . -type f -exec sed -i.bak 's|^<\/s>\s\(.*\)\s<\/s>.*$|\1|' {} \;

This command will create a .bak file for each changed file.

Notes:

  • The -i argument for sed command is a GNU extension, so, if you are running this command with the BSD's sed you will need to redirect the output to a new file then rename it.
  • Although specified in POSIX, some find implementations do not have the -exec argument, so, you will need to use a | xargs instead.
0

I propose this:

sed 's;^[[:blank:]]*<[^>]*>[[:blank:]]*\(.*\)<.*>.*$;\1;' foo

Output:

Text here that I want to keep

This works if the tags have more than one letter, and any letter, and removing any white space at begginig and end, example:

<br> Text here that I want to keep    </br> (31ca4166c37a_.76)
0
0

You can try with below command

command

sed  -e 's/<\/\?s>//g' -e 's/(.*)//g' filename

output

Text here that I want to keep
0

With any POSIX awk (assumes that every <s> and </s> do come in ordered pairs on every line like in the sample input you provided):

$ awk -F'[[:blank:]]*</?s>[[:blank:]]*' '{print $2}' file
Text here that I want to keep

With GNU awk for \s shorthand:

$ gawk -F'\\s*</?s>\\s*' '{print $2}' file
Text here that I want to keep

With any POSIX sed:

$ sed 's|[[:blank:]]*<s>[[:blank:]]*\(.*[^[:blank:]]\)[[:blank:]]*</s>.*|\1|' file
Text here that I want to keep

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .