Is there any script for removing the words in the line for example these:
"my_name/your_name/ours_name/name"
"my_name/name"
I want to remove the words within the double quotes and before the last slash. Whatever the word appear, I need to remove it. After removing, both of them should be:
"name"
To be more specific: I have one folder, in that folder there are multiple files. Each file consists of a header file like #include "my_name/ur_name/name". I want it to be #include "name", because I want to make that header in the current directory.
you can try the below command,
Commmand:
sed -i 's|#include "my_name/ur_name/name"|#include "name"|g' *
Description:
command will replace (#include "my_name/ur_name/name") with (#include "name") into all the files of directory
NOTE:
Command immediately returns "OK" message,But it will take time to perform the internal file operations.
Shell file
Create a file called main.sh and copy this:
#Get parameter.
string=$1
#Explode string to array.
IFS='/' read -a array <<< "$string"
#Get array size.
size=${#array[#]}
#Get last array element.
echo ${array[$size-1]}
BASH usage
Now you can call main.sh with the path between double quotes as a parameter and it will return the last segment.
$bash -f main.sh "my_name/your_name/ours_name/name"
name
$bash -f main.sh "my_name/name"
name
Maybe you should also look at this question: Take the last part of the folder path in shell
A Simple one line will do this
file.txt
"my_name/your_name/ours_name/name"
"my_name/x_name"
Command
sed 's/^"//g' file.txt | awk 'BEGIN {FS="/"} {print $NF}' | sed 's/^/"/g'
Output
"name"
"x_name"
Related
I have downloaded some 90 fasta files from NCBI for bacterial genomes. The downloaded files have default names given by NCBI. I need to change it to my desired file names. Thus I have created two .txt files:
file1.txt - having the default files names provided by NCBI. listed out the names provided by NCBI in file1.txt
file2.txt - having the names to replace the default. listed out the names to replace the NCBI names
Both the files are made in an order so that 1st entry of file1.txt is corresponding to 1st entry of file2.txt.
Now all the downloaded files are in a folder. the folder having the files
and I need a script which reads file1.txt, matches with the file name in the folder and replace it with the names in file2.txt.
I am not a bioinformatician, new to this genre. I look forward to your help. Can this process be made simpler?
This can done with a very small awk one-liner. For convenience, lets first combine your file1 and file2 to make processing easier. This can be done with paste file1.txt file2.txt >> names.txt.
names.txt will be a text file with the old names in the first column and the new names in the second. Awk lets us conveniently run through a file line-by-line (or record-by-record in its terminology) and access each column/field.
Assuming you are in the directory with all these files, as well as names.txt, you can simply run awk '{system("mv " $1 " " $2)}' names.txt to transform them all. This will run through all the lines in names.txt, take the filename given in the first column, and move it to the name given in the second column. The system command allows you to access more basic file system operations through the shell, like moving mv, copying cp, or removing rm files.
Use paste
and xargs like so:
paste file1.txt file2.txt | xargs --verbose -n2 mv
The command is using paste to write lines from 2 files side by side, separated by TABs, to STDOUT. The STDOUT is read by xargs using a pipe (|). Option --verbose prints the command, and option -n2 specifies the max number of arguments for xargs to be 2, so that the resulting commands that are executed are something like mv old_file new_file.
Alternatively, use the Perl one-liners below.
Print the commands to rename the files, without executing the commands ("dry run"):
paste file1.txt file2.txt | perl -lane '$cmd = "mv $F[0] $F[1]"; print $cmd;'
Print the commands to rename the files, then actually execute them:
paste file1.txt file2.txt | perl -lane '$cmd = "mv $F[0] $F[1]"; print $cmd; system $cmd;'
The command is using paste to write lines from 2 files side by side, separated by TABs, to STDOUT. The STDOUT is read by the Perl one-liner using a pipe (|) to pass it to Perl one-liner's STDIN.
The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.
-a : Split $_ into array #F on whitespace or on the regex specified in -F option.
$F[0], $F[1] : first and second elements of the array #F into which the line is split. They are old and new file names, respectively.
system executes the command $cmd, which actually moves the files.
SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches
I have looked for an answer to what seems like a simple question, but I feel as though all these questions (below) only briefly touch on the matter and/or over-complicate the solution.
Read a file and split each line into two variables with bash program
Bash read from file and store to variables
Need to assign the contents of a text file to a variable in a bash script
What I want to do is read specific lines from a file (titled 'input'), store them variables and then use them.
For example, in this code, every 9th line after a certain point contains a filename that I want to store as a variable for later use. How can I do that?
steps=49
for((i=1;i<=${steps};i++)); do
...
g=$((9 * $i + 28)) #In.omega filename
`
For the bigger picture, I basically need to print a specific line (line 9) from the file whose name is specified in the gth line of the file named "input"
sed '1,39p;d' data > temp
sed "9,9p;d" [filename specified in line g of input] >> temp
sed '41,$p;d' data >> temp
mv temp data
Say you want to assign the 49th line of the $FILE file to the $ARG variable, you can do:
$ ARG=`cat $FILE | head -49 | tail -1`
To get line 9 of the file named in the gth line of the file named input:
sed -n 9p "$(sed -n ${g}p input)"
arg=$(cat sample.txt | sed -n '2p')
where arg is variable and sample.txt is file and 2 is line number
I'm new to OSX command line tools.
I am trying to find a block of text in a file and append this text at the end of all lines in another text file. At run time I don't know what this text will be, I just know it will be located within "BEGINHMM" and "ENDHMM". Also, I don't know the makeup of the destination file, except for that it will not be an empty text file.
The command which finds the block of text of interest is:
sed -n '/<BEGINHMM>/,/<ENDHMM>/p' proto
where "proto" is a text file containing the text of interest.
I've been trying to pipe the output of the above command to another 'sed' command, in the following manner:
xargs -I '{}' sed -i .bak 's/$/{}/' monophones0.txt
but I am getting some bizarre results, I see the "{}" inserted in the text for example.
I've also tried piping to:
xargs -0 sed -i .bak 's/$/&/' monophones0.txt
but I just get the printout (similar to terminal echo) of the text I am trying to grab.
Ultimately I want to loop over several 'proto' files in multiple directories and copy the text between the "BEGINHMM", "ENDHMM" block in each directory, and append the selected text to that directory's monophones.txt lines.
I am running the commands in the terminal, bash, OSX 10.12.2
Any help would be appreciated.
(1) Your sed command is of the form sed -n '/A/,/B/p'; this will include the lines on which A and B occur, even if these strings do not appear at the beginning of the line. This form may have other surprises in store for you as well (what do expect will happen if B is missing or repeated?), but the remainder of this post assumes that's what you want.
(2) It's not clear how you intend to specify the "proto" files, but you do indicate they might be in several directories, so for the remainder of this post, I'll assume they are listed, one per line, in a file named proto.txt in each directory. This will ensure that you don't run into any limitations on command-line length, but the following can easily be modified if you don't want to create such a file.
(3) Here is a script which will use the sed command you've mentioned to copy segments from each of the "proto" files specified in a directory to monophones0.txt in the directory in which the script is executed.
#!/bin/bash
OUT=monophones0.txt
cat proto.txt | while read file
do
if [ -r "$file" ] ; then
sed -n '/<BEGINHMM>/,/<ENDHMM>/p' "$file" >> $OUT
elif [ -n "$file" ] ; then
echo "NOT FOUND: $file" >&2
fi
done
Just like what you did before. tmpfile=$(mktemp); sed -n '/<BEGINHMM>/,/<ENDHMM>/p' proto >$tmpfile; sed -i .bak "r $tmpfile" monophones0.txt; rm $tmpfile. This is the basic idea; there are other checks you need to perform to make this a robust script.
– 4ae1e1
I have txt file which listed with some line. Each line has image names included. What I want is, The shell script that edit same txt file OR copy particular image name to new file.
This is my txt file having list of images with their paths.
And I want output like this:
I want only image names should be extract from those lines.
You can use this awk,
awk '{ split($1,arr,"/"); print arr[length(arr)] }' yourfile > output.txt
Using gnu sed you can do:
sed -r 's~^[^[:blank:]]*/([^/ ]+) .*$~\1~' file
1.png
1#2x.png
2.png
2#2x.png
3.png
You can do something like:
cat the_file.txt|while read file; do
echo $(basename $file)
done
And (if needed) redirect the output on another file.
while read fn rest
do
basename "$fn"
done < file.txt
This will read your input line by line. It will put the filename (including path) into the fn variable, and whatever is on the rest of the line into rest. Then it uses the basename command to strip off the path and just print out the filename itself.
This is another sed solution that doesn't use extended regular expression (more portable solution):
sed 's/^.*\/\([^[:blank:]\/]*\)[[:blank:]].*$/\1/' sourceFile > destFile
You have to replace sourceFile and destFile white the path to oridinal and destination file respectively.
The command look for any string without blank char or slashes \([^[:blank:]\/]*\) preceeded by a slash ^.*\/ and followed by a blank char [[:blank:]].*$ than the patter is substitituded with the first matching string /\1/.
You could read a quick sed reference here.
I just got into bash so I decided to write my first script. To give you a little background I want to write a script that will back up my Documents folder onto a USB stick whenever I connect the USB stick. (I am aware that software like this exists).
I have two strings at the beginning of the script:
directoryPath="/Users/USER/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
For loops gives me absolute path to a file like this
/Users/USER/Documents/Comics/Bleach/Volume 004/bleach_031.zip
Until now I was using sed like this
newPath=`echo "$file" | sed "/Users\/USER\/Documents/s//Volumes\/backMeUp\/main/"`
But since I want my script to be more "open" and other-user-friendly I want to get rid of this line and make it some other way.
I also tried this with different syntax
echo $file | sed -e "s/$directoryPath/$backupPath/"
but with no luck.
My question is how can I remove part of a string with $directoryPath and replace it with $backupPath?
basename (and dirname) are your friend(s).
Something like this:
#!/bin/bash
directoryPath="/Users/rojcyk/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
f=$(basename '/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip')
echo ${backupPath}/${f}
Updated
#!/bin/bash
directoryPath="/Users/rojcyk/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
f='/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip'
# delete shortest match of substring from front of string
new_f=${f#$directoryPath}
echo ${backupPath}${new_f}
Output:
/Volumes/backMeUp/main/Comics/Bleach/Volume 004/bleach_031.zip
Read more about bash string operations here
With bash:
directoryPath="/Users/rojcyk/Documents"
backupPath="/Volumes/backMeUp/main"
f="/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip"
echo "${backupPath}/${f#$directoryPath}"
Produces
/Volumes/backMeUp/main//Comics/Bleach/Volume 004/bleach_031.zip
The double slash in the middle is OK. If you don't want it: "${backupPath}/${f#$directoryPath/}"
is this what you want?
kent$ cat t
$foo$bar$blah
kent$ sed 's/\$foo/\$xxx/g' t
$xxx$bar$blah
or this?
kent$ echo $foo
/f/o/o
kent$ echo $bar
/b/a/r
kent$ cat t
something /f/o/o
kent$ sed "s:$foo:$bar:" t
something /b/a/r
sed -e "s/$directoryPath/$backupPath/"
You're on the right path, just need to manipulate the two path variables first.
The contents of $directoryPath is /Users/rojcyk/Documents, so your sed command is coming out as sed -e "s//Users/rojcyk/Documents//Volumes/backMeUp/main/". You need to escape the directory slashes so they don't affect the sed command.
Try this:
directoryPathEscaped=`echo $directoryPath | sed -e "s/\\//\\\\\\\\\//g"`
backupPathEscaped=`echo $backupPath| sed -e "s/\\//\\\\\\\\\//g"`
# At this point, directoryPathEscaped is equal to "\/Users\/rojcyk\/Documents"
# Now you can do your original command line, with the new variables.
sed -e "s/$directoryPathEscaped/$backupPathEscaped/"