Sort File List in Xcode? - xcode

Is there a way in Xcode to sort my list of files under say the Classes folder Alphabetically?
I know I can drag them around, but with tons of files that is a pain.
I am surprised I can not right click on the folder and say to sort.

Click on the folder, and then click Edit > Sort > By Name

Here is a Ruby script that will sort all the files within their respective groups in an Xcode 4 project file (probably Xcode 3 as well but I haven't tried that).
Usage:
ruby sort.rb <infile> <outfile>
where <infile> is an unsorted .pbxproj file and <output> will be the sorted version. Don't make them the same file.
#!/usr/bin/env ruby
state = :primary
group = []
file_count = group_count = 0
File.open ARGV[0] do |infile|
File.open ARGV[1], 'w' do |outfile|
infile.each_line do |line|
case state
when :primary
# copy lines until and including "children = ("
outfile.write line
state = :group if line =~ /^\s*children\s*=\s*\x28\s*$/
when :group
if line =~ /^\s*[0-9A-F]+\s*\/\* (.*) \*\/,\s*$/
# add file to current group if "<guid> /* <filename> */,"
group << [$1,line]
file_count += 1
else
# otherwise, output sorted files,
# empty the group, and go back to primary state
group.sort.each do |fn,ln|
outfile.write ln
end
state = :primary
group = []
outfile.write line
group_count += 1
end
end
end
end
end
puts "Sorted #{file_count} files in #{group_count} groups"

The ruby script from jedediah works great. To also sort resources being copied, you can add:
state = :group if line =~ /^\s*files\s*=\s*\x28\s*$/
Note that sort is case sensitive (capital letters first). To make it insensitive, use:
group << [$1.downcase,line]

There isn't really an easy solution in XCode5.
I opened the pbxproj file in a text editor.
Navigate down to /* Begin PBXResourcesBuildPhase section */
select everything in files.
copy to a new text document.
Replace /* with \t (tab character)
select all, copy and paste into blank excel document. you should have 2 columns of data
insert a column at poisition 2
make all rows for that column /*
sort the sheet on column 3
copy all data and paste back over your section in pbxproj file
save file
That should sort the "Copy Bundle Resources" section of your project.
I feel dirty just doing this, but hey - it works

Czar there are advantages to having it the way you want, instead of automatically having it sort at all times.
Some classes might be related in some way, but the names aren't right next to each other, I've used that for certain. :)

Related

How to get file count with Ruby

I have the following code :
system('cls')
Dir.chdir("testing")
puts Dir.pwd
Dir.glob('*.csv').each do|csv_filename|
next if csv_filename == '.' or csv_filename == '..'
puts "\t" + csv_filename
end
file_Num= Dir[".testing/*"].length
puts "file count = " + file_Num.to_s
I am trying to display all csv filenames within the testing directory and get a count of such csv files, not directories. The above renders only the correct csv file names as expected but file count always = 0. Yes, I am new trying to teach myself Ruby but I've searched for what I am trying to accomplish and cannot seem to put the pieces together. I need a file count because if that num is > 3 I would like to send an alert to the screen of some type. Wold appreciate any help on this. Thanks!
Look like you put the wrong path in file_Num= Dir[".testing/*"].length
Should be
file_Num = Dir["*.csv"].length
as you already change dir to testing.
In case you would like to count all csv files in subdirectories
file_Num = Dir["**/*.csv"].length

Ruby file renamer

this is a text file renamer i made, you throw the file in a certain folder and the program renames them to file1.txt, file2.txt, etc
it gets the job done but it's got two problems
it gives me this error no implicit conversion of nil into String error
if i add new files into the folder where there's already organized files, they're all deleted and a new file is created
what's causing these problems?
i=0
Dir.chdir 'C:\Users\anon\Desktop\newfolder'
arr = Dir.entries('C:\Users\anon\Desktop\newfolder')
for i in 2..arr.count
if (File.basename(arr[i]) == 'file'+((i-1).to_s)+'.txt')
puts (arr[i]+' is already renamed to '+'file'+i.to_s)
else
File.rename(arr[i],'file'+((i-1).to_s)+'.txt')
end
end
There are two main problems in your program.
The first is that you are using an out of bounds value in the array arr. Try this a = [1,2,3]; a[a.count] and you will get nil because you are trying at access a[3] but the last element in the array has index 2.
Then, you are using as indexes for names fileINDEX.txt always 2...foobar without taking into account that some indexes may be already used in your directory.
Extra problem, you are using Dir.entries, this in my OS gives regular entries more . and .. which should be managed properly, they are not what you want to manipulate.
So, I wrote you a little script, I hope you find it readable, to me it works. You can improve it for sure! (p.s. I am under Linux OS).
# Global var only to stress its importance
$dir = "/home/p/tmp/t1"
Dir.chdir($dir)
# get list of files
fnames = Dir.glob "*"
# get the max index "fileINDEX.txt" already used in the directory
takenIndexes = []
fnames.each do |f|
if f.match /^file(\d+).txt/ then takenIndexes.push $1.to_i; end
end
# get the first free index available
firstFreeIndex = 1
firstFreeIndex = (takenIndexes.max + 1) if takenIndexes.length > 0
# get a range of fresh indexes for possible use
idxs = firstFreeIndex..(firstFreeIndex + (fnames.length))
# i transform the range to list and reverse the order because i want
# to use "pop" to get and remove them.
idxs = idxs.to_a
idxs.reverse!
# rename the files needing to be renamed
puts "--- Renamed files ----"
fnames.each do |f|
# if file has already the wanted format then move to next iteration
next if f.match /^file\d+.txt/
newName = "file" + idxs.pop.to_s + ".txt"
puts "rename: #{f} ---> #{newName}"
File.rename(f, newName)
end

How to read a file's content and search for a string in multiple files

I have a text file that has around 100 plus entries like out.txt:
domain\1esrt
domain\2345p
yrtfj
tkpdp
....
....
I have to read out.txt, line-by-line and check whether the strings like "domain\1esrt" are present in any of the files under a different directory. If present delete only that string occurrence and save the file.
I know how to read a file line-by-line and also know how to grep for a string in multiple files in a directory but I'm not sure how to join those two to achieve my above requirement.
You can create an array with all the words or strings you want to find and then delete/replace:
strings_to_delete = ['aaa', 'domain\1esrt', 'delete_me']
Then to read the file and use map to create an array with all the lines who doesn't match with none of the elements in the array created before:
# read the file 'text.txt'
lines = File.open('text.txt', 'r').map do|line|
# unless the line matches with some value on the strings_to_delete array
line unless strings_to_delete.any? do |word|
word == line.strip
end
# then remove the nil elements
end.reject(&:nil?)
And then open the file again but this time to write on it, all the lines which didn't match with the values in the strings_to_delete array:
File.open('text.txt', 'w') do |line|
lines.each do |element|
line.write element
end
end
The txt file looks like:
aaa
domain\1esrt
domain\2345p
yrtfj
tkpdp
....
....
delete_me
I don't know how it'll work with a bigger file, anyways, I hope it helps.
I would suggest using gsub here. It will run a regex search on the string and replace it with the second parameter. So if you only have to replace any single string, I believe you can simply run gsub on that string (including the newline) and replace it with an empty string:
new_file_text = text.gsub(/regex_string\n/, "")

Ruby: How do you search for a substring, and increment a value within it?

I am trying to change a file by finding this string:
<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]>
and replacing {CLONEINCR} with an incrementing number. Here's what I have so far:
file = File.open('input3400.txt' , 'rb')
contents = file.read.lines.to_a
contents.each_index do |i|contents.join["<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]></aspect>"] = "<aspect name=\"lineNumber\"><![CDATA[#{i}]]></aspect>" end
file.close
But this seems to go on forever - do I have an infinite loop somewhere?
Note: my text file is 533,952 lines long.
You are repeatedly concatenating all the elements of contents, making a substitution, and throwing away the result. This is happening once for each line, so no wonder it is taking a long time.
The easiest solution would be to read the entire file into a single string and use gsub on that to modify the contents. In your example you are inserting the (zero-based) file line numbers into the CDATA. I suspect this is a mistake.
This code replaces all occurrences of <![CDATA[{CLONEINCR}]]> with <![CDATA[1]]>, <![CDATA[2]]> etc. with the number incrementing for each matching CDATA found. The modified file is sent to STDOUT. Hopefully that is what you need.
File.open('input3400.txt' , 'r') do |f|
i = 0
contents = f.read.gsub('<![CDATA[{CLONEINCR}]]>') { |m|
m.sub('{CLONEINCR}', (i += 1).to_s)
}
puts contents
end
If what you want is to replace CLONEINCR with the line number, which is what your above code looks like it's trying to do, then this will work. Otherwise see Borodin's answer.
output = File.readlines('input3400.txt').map.with_index do |line, i|
line.gsub "<aspect name=\"lineNumber\"><![CDATA[{CLONEINCR}]]></aspect>",
"<aspect name=\"lineNumber\"><![CDATA[#{i}]]></aspect>"
end
File.write('input3400.txt', output.join(''))
Also, you should be aware that when you read the lines into contents, you are creating a String distinct from the file. You can't operate on the file directly. Instead you have to create a new String that contains what you want and then overwrite the original file.

Copy a list of files from one directory to another - How to put text file into array?

Longtime lurker, first time posting! I'm new to Ruby so I would love some help on this.
I have a large text file with a list of files separated by a break, so it looks like this:
ARO_9501.jpg
ARO_9506.jpg
IMG_1499.jpg
IMG_1511.jpg
How can I get this text file into an array so I can call .each on it and copy the files to another directory?
This is how I generally do:
fileNameArray = File.read("/path/to/file.txt").split("\n")
Or, if you just need to iterate over the file names and don't necessarily need an array containing the names (it looks like you don't), I usually use this:
File.read("/path/to/file.txt").each_line do |line|
# do operations using line
end
Docs:
IO::read (File extends IO)
String .split() and each_line()
You can go this way also using IO::readlines :
ar = File.open("/home/kirti/ruby/foo.txt","r") do |fil|
fil.readlines.map(&:strip)
end
p ar
# >> ["ARO_9501.jpg", "ARO_9506.jpg", "IMG_1499.jpg", "IMG_1511.jpg"]
As per the #steenslag comments:
ar = File.readlines("/home/kirti/ruby/foo.txt").map(&:chomp)
ar # => [ "ARO_9501.jpg", "ARO_9506.jpg", "IMG_1499.jpg", "IMG_1511.jpg"]

Resources