Word length and substitute using sed - bash [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a file that looks like this:
hell hi tell smith david
abc def ab abcd
123456 123ab
I would like to reverse all the words with length 3 and 4, to get output like this:
lleh hi llet smith david
cba fed ac abcd
123456 123ab
How can I do that using strictly only sed?

Here you go:
sed -re 's/\<(.)(.)(.)\>/\3\2\1/g'
Explanation:
The -r flag is to be able to use extended regular expressions. It's specific to GNU sed. Without this, I would have to write the pattern as: \<\(.\)\(.\)\(.\)\>
\< matches beginning of a word, and \> the end. Both have zero length.
Things matched within (...) can be used in the replacement as \1 for the first expression, \2 for the second (...), and so on.
The g flag at the end is to replace all occurances on the same line, not only the first
In short, the search pattern matches words of length 3, and replaces them with their letters reversed.
I see you updated your example, and you want to reverse words with length 4 too. To do that you can add another expression following the same logic, like this:
sed -re 's/\<(.)(.)(.)\>/\3\2\1/g' -e 's/\<(.)(.)(.)(.)\>/\4\3\2\1/g'

Related

How to find all lines which contain at least one of a set of words as a prefix [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a text file of words, one per line, called A.
I have another text file B.
How can I find all lines in B what have at least one of the words from A as a prefix?
I was hoping to be able to do this from the command line maybe using grep but any other command line solution would be great too.
For example, if A is
apple
bob
cheese
and B is
aple
bob123
ches
I would like the line bob123 to be returned.
One approach uses bash's process substitution and sed to add a regular expression beginning-of-line ^ anchor to each line of A, and then tells grep to use it as a list of regular expressions to search for:
$ grep -f <(sed 's/^/^/' a.txt) b.txt
bob123

Match pattern in line using grep [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I need to grep lines from a file with comma separated values, and direct the output to another file. Thus, if the second value starts with 'U' and the last value is 'Success', then this line matches the pattern.
Should match the pattern:
324,U63#DOM1,U63#DOM1,C1755,C1755,Kerberos,Network,LogOn,Success
Should fail to match:
456,C1164$#DOM1,C1164$#DOM1,C625,C625,?,Network,LogOff,Success
123,U63#DOM1,C11847$#?,C2109,C2109,?,?,TGT,Fail
Thank you!
As columnar matching requirements become more complex, an awk solution becomes more attractive:
awk -F, '$2 ~ /^U/ && $(NF) == "Success"'
(The default action of the match is to print the line.)
Here is the solution using grep though:
grep '^[^,]*,U.*,Success$'
And sed:
sed '/^[^,]*,U.*,Success$/ p; d'
grep '^[^,]*,U.*,Success$'
Look for the first comma, a U, the last comma, Success and end of line.

How to remove specific characters from a string? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am brand new to Perl and struggling with it.
I need to learn just the basics and not much.
I googled and got no simple answer to my question.
I have a string which contains numbers, dots, dashes, colon: and two alphabets.
I want to replace one alphabet by a space and the other by nothing.
How do I do this?
Is there no string.ReplaceChar(theChar, replacement)?
You can try as in the example below:
From commandline:
To replace only the first occurrence of the alphabets:
sdlcb#ubuntu:~$ echo "123.-A456:7B9AB0" | perl -pe 's/A//; s/B/ /'
123.-456:7 9AB0
To replace all occurrences of the alphabets:
sdlcb#ubuntu:~$ echo "123.-A456:7B9AB0" | perl -pe 's/A//g; s/B/ /g'
123.-456:7 9 0
Within script:
#!/usr/bin/perl -w
use strict;
my $data = "123.-A456:7B9AB0";
my $final_data = $data;
$final_data =~ s/A// ;
$final_data =~ s/B/ /;
print "data: $data\n";
print "final_data: $final_data\n";
Use g for substituting all occurrences.
Perl lends itself to using regular expressions, so that is how I would approach it;
#!/usr/bin/perl -w
use strict;
my $ALPHABET = 'abcde';
my $source_data = "1.2.3-$ALPHABET:$ALPHABET";
my $dest_data = $source_data
$dest_data =~ s/(-)$ALPHABET(:)/$1 $2/;
print "source_data: $source_data\n";
print "dest_data: $dest_data\n";
--->
source_data: 1.2.3-abcde:abcde
dest_data: 1.2.3- :abcde
Here the reqular expresion operator (=~) is substituting the first occurance of the pattern (-)$ALPHABET(:) with a '- :' string.
This pattern is using capture groups '()' to locate the match within the data.
Depending on your data you will likely need to adjust the patterns in the capture groups.
The backrefernces $1 and $2 within the match are used for demonstration purposes.
We could help with a more specific regex if you include example data in your question.

How to add a character in front of multiple words in linux [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Here is a text file containing many words,each is separated by space breaks or line breaks.
Now I want to add a character,like "#" "$" "#" in front of each of them,
and I found doing this job one by one will take too much time,
are there any better ways,in bash?
Try using sed
sed -r 's/([^ ]+)/#\1/g' file
Or more concisely,
sed -r 's/[^ ]+/#&/g' file
Sample input
abc def pqr-stu xyz
Output
#abc #def #pqr-stu #xyz
Using sed, you could say:
sed 's/\b\w/#&/g' inputfile
This would append # before every word.

file renaming (take 1 part of filename and transfer it to 'beginning' of filename) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
Ok, i have a lot of files which all contain a version number v1 or v2. And i want to match the filenames to other files which are composed as the second file like this:
train.v1_GENENAME_ID.debruijn.txt (this is what i want)
The first file is composed like this:
train.GENENAME_ID_v1.debruijn.txt
And so the v1 should move before the GENENAME. All the version identifiers are the same. Namely v1 or v2
lets say i have a file called: 'train.Glis2_1757.2_v1_deBruijn.txt' and i want to convert it to this 'train.v1_Glis2_1757.2_deBruijn.txt'
Is there a easy way to take the v1 from first filename and place it as in the 2nd filename?
I was thinking about combining grep with a if statement. But still not managed to make it work.
Any hints/tips are appreciated.
Use the rename distributed with perl:
rename 's/(train.)(.*_)(v[0-9].)(deBruijn.txt)/$1$3$2$4/' *
On some systems it is called 'ren' or 'pren'.
Here is one using a for loop and using sed to transform the filenames
for f in *.txt;
do
nf=$(echo $f | sed -r 's/([^.]+\.)([^.]+\.)([0-9])_([^_]+)(.*)/\1\4_\2\3\5/')
echo mv $f $nf
done
If you are satisfied with the results you can remove echo and let the rename happen
As per your request here is the annotated version explaining how the various parts are extracted and rearranged to fit the desired output
echo "train.Glis2_1757.2_v1_deBruijn.txt" | sed -r
's/([^.]+\.) # match all non-dot characters (+ meaning one or more) followed by a dot and store in group 1 (train.)
([^.]+\.) # match all non-dot characters followed by a dot and store in group 2 (Glis2_1757.)
([0-9]) # match a single digit and store in group 3 (2)
_
([^_]+) # match all non-underscore characters and store in group 4 (v1)
(.*) # match all that follow . is a wildcard char in regex and * is for zero or more (_deBruijn.txt)
/\1\4_\2\3\5/' # rearranging the matches to get desired output
You can do this in shell with parameter expansion, specifically suffix and prefix removal:
FN=train.Glis2_1757.2_v1_deBruijn.txt
STRIPPED=${FN%_deBruijn.txt} # "train.Glis2_1757.2_v1"
GENEVERS=${STRIPPED#train.} # "Glis2_1757.2_v1"
VERSION=${GENEVERS##*_} # "v1"
GENENAME=${GENEVERS%_v[12]} # "Glis2_1757.2"
NEWFN=train.${VERSION}_${GENENAME}_deBruijn.txt # "train.v1_Glis2_1757.2_deBruijn.txt"
mv $FN $NEWFN
You don't have to go through all the explicit naming steps above, but I think that's clearer. Also, this technique could be extrapolated to have arbitrary prefixes (other than "train.") and suffixes (other than "_deBruijn.txt") presuming you can represent them with shell pattern notation.

Resources