1

I have a file with links like this:

http://domain.com/file_name1.mkv
http://domain.com/file_name2.mkv
http://domain.com/file_name3.mkv

... and so on.

I want to create a file for each link with extension .strm and each file to have the name of the file name and to contain the link for that file. So, for the first link the first file name will be file_name1.strm and contain the first link, for the second link the file name will be file_name2.strm and will contain the second link, and so on. How can i do that?

I have a command that is doing something close but it creates only files with the names from words in a file:

sed -e 's/$/.strm/' file | xargs -d '\n' touch
user1800997
  • 225
  • 2
  • 10

3 Answers3

2

To elaborate your xargs attempt

xargs -L1 sh -c 'f="${0##*/}"; printf "%s\n" "$0" > "${f%.*}.strm"' < file

The first substitution f="${0##*/}" removes the path components of the URL, while the second "${f%.*}.strm" removes and replaces the extension.

Ex.

$ xargs -L1 sh -c 'f=${0##*/}; printf "%s\n" "$0" > "${f%.*}.strm"' < file
$ head *.strm
==> file_name1.strm <==
http://domain.com/file_name1.mkv

==> file_name2.strm <==
http://domain.com/file_name2.mkv

==> file_name3.strm <==
http://domain.com/file_name3.mkv
steeldriver
  • 81,074
2

I'll try to rehabilitate the pure-bash solution proposed by @Erwan:

while IFS= read -r link; do
    filename="${link##*/}"
    echo "$link" > "${filename%.mkv}.strm"
done < file
  1. See https://unix.stackexchange.com/a/209184/230365 for explanation why one should use IFS= read -r to read a line
  2. ${var##<pattern>} substitutes a variable with longest prefix matching the removed. See "Remove matching prefix pattern" in section "Parameter Expansion" in bash(1). There are a lot of other useful parameter expansion modificators
  3. ${var%<pattern>} substitutes a variable with shortest suffix matching the removed ("Remove matching suffix pattern")
belkka
  • 481
0

Edited to fix the errors mentioned in the comments, but bellka's answer is a better version of this solution.

The following reads the links in file line by line. Each link is written to a file named with the base name of the link followed by the required ending.

while read link; do
   echo "$link" >$(basename "${link%.mkv}").strm
done <file

The same as a one liner:

cat file | while read link; do echo "$link" >$(basename "${link%.mkv}").strm; done
Erwan
  • 219
  • 2
    Issues: The links contain /, so the shell will interpret them as files in weirdly named subdirectories. The variables are unquoted, which may possibly be problematic if any link contains a filename globbing character. No input data is given to the loop. No explanation given in the answer. – Kusalananda Dec 28 '18 at 18:43
  • 2
    it also doesn't extract the filename from the end of the link, as requested. – Jeff Schaller Dec 28 '18 at 20:47
  • I've removed my downvote as the edit has resolved the issues outlined by Kusalananda (although it does not resolve the one outlined by Jeff). – Anthony Geoghegan Dec 30 '18 at 01:47
  • I've seen the subsequent edits so I've now upvoted this answer. BTW, you don't need the cat for a one-liner version. An extra semi-colon is enough: while read link; do echo "$link" >"$(basename "${link%.mkv}").strm"; done <file. Nice work on improving this answer. – Anthony Geoghegan Jan 04 '19 at 12:41